<template>
  <div v-if="visible" ref="refmodel">
    <a-modal
      v-model:visible="visible"
      @ok="handleOk"
      ok-text="确定"
      cancel-text="取消"
      :width="700"
      title="文件管理"
      wrapClassName="img-model"
      :getContainer="() => $refs.refmodel"
    >
      <div style="padding: 10px">
        <div class="img-header">
          <a-form class="search-form" layout="inline">
            <a-form-item label="">
              <a-input-search placeholder="文件名称" @search="onSearch">
                <template #enterButton>
                  <a-button>查询</a-button>
                </template>
              </a-input-search>
            </a-form-item>
            <div class="img-header-right" v-if="showUpload">
              <span class="info">不能超过{{ maxUpload }}M</span>
              <a-upload
                :accept="accepts"
                name="file"
                :showUploadList="false"
                :multiple="true"
                :remove="handleRemove"
                :before-upload="beforeUpload"
              >
                <a-button>
                  <UploadOutlined />
                  选择文件
                </a-button>
              </a-upload>
            </div>
          </a-form>
        </div>
        <div class="img-operation">
          <!-- <a-checkable-tag> 名称 </a-checkable-tag>
          <a-checkable-tag> 类型 </a-checkable-tag>
          <a-checkable-tag> 大小 </a-checkable-tag> -->
        </div>
        <div class="img-list" v-scrollBar>
          <a-row :gutter="10">
            <a-col v-for="(item, key) in dataList" :key="key" :span="4">
              <div
                class="img-item"
                :title="item.name + '【点击文字选中】'"
                @click="activeChange(item.storage_id)"
              >
                <div class="img-content">
                  <!-- 为图片 -->
                  <a-image
                    v-if="item.type == 'img'"
                    width="100%"
                    maxHeight="100%"
                    :placeholder="true"
                    :preview="false"
                    :fallback="fallback"
                    :src="item.src"
                  />
                  <!-- 为视频 -->
                  <video
                    v-else-if="item.type == 'video'"
                    width="100"
                    height="100"
                    maxHeight="110"
                    controls="controls"
                    :src="item.src"
                  ></video>
                  <!-- 为音频 -->
                  <audio
                    v-else-if="item.type == 'audio'"
                    width="100"
                    height="100"
                    maxHeight="110"
                    controls="controls"
                    :src="item.src"
                  ></audio>
                  <!-- 为附件压缩包时候 -->
                  <FileZipOutlined
                    v-else-if="item.type == 'zip'"
                    style="font-size: 80px; color: #f9b837"
                  />
                  <!-- 不知名文件 -->
                  <FileOutlined
                    v-else
                    style="font-size: 80px; color: #d9d9d9"
                  />
                </div>
                <div class="img-title">{{ item.name }}</div>
                <div
                  class="img-select-mask"
                  v-if="in_array(item.storage_id, activeList)"
                >
                  <CheckCircleOutlined class="img-select-mask-check" />
                </div>
              </div>
            </a-col>
          </a-row>
        </div>
        <div class="img-footer">
          <div>
            <span class="img-footer-info"
              >已选 <b>{{ activeList.length }}</b> 项</span
            >

            <!-- <a-button type="dashed"  size="small" class="img-footer-group">移动选中</a-button> -->
            <a-button v-if="showDel" type="dashed" size="small" @click="deletes" danger
              >删除选中</a-button
            >
          </div>
          <div class="img-footer-right">
            <a-pagination
              v-model:current="form.page"
              :total="total"
              :pageSize="listRows"
              show-less-items
              @change="changePage"
            />
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>
<script>
import { defineComponent, toRefs, reactive } from "vue";
import { CheckCircleOutlined } from "@ant-design/icons-vue";
import {
  UploadOutlined,
  FileOutlined,
  FileZipOutlined,
} from "@ant-design/icons-vue";
import { json, notice, in_array, isEmptyObject, deepCopy } from "@/config";
import {
  batchUpload,
  getList,
  geIdsList,
  fileIdDelete,
} from "@/api/upload/File";
export default defineComponent({
  components: {
    CheckCircleOutlined,
    UploadOutlined,
    FileOutlined,
    FileZipOutlined,
  },
  props: {
    // 选中的ID集列表，不传为不选
    active: {
      type: Array,
    },
    // 限制选中值，不传为不限制
    limit: {
      type: Number,
    },
    // 显示删除按钮，默认不显示
    showDel: {
      type: Boolean,
    },
    // 显示上传按钮，默认不显示
    showUpload: {
      type: Boolean,
    },
  },
  setup(props, { emit }) {
    let state = reactive({
      visible: false,
      // 选中列表
      activeList: [],
      // 上传列表
      uploadList: [],
      // 最大上传多少M
      maxUpload: 1,
      form: {
        search: "",
        page: 1,
      },
      total: 0,
      listRows: 18,
      // 文件限制类型
      accepts: "image/png,image/jpeg,video/mp4,audio/mp3",
      // 展示列表
      dataList: [],
      filesList: [],
      fallback:
        "",
    });
    // 获取列表
    const getListfun = () => {
      getList(state.form).then((res) => {
        const list = res.data.list;
        state.dataList.length = 0;
        for (const key in list) {
          let type = "file";
          if (in_array(list[key]["file_ext"], ["jpg", "png", "gif", "jpeg"])) {
            type = "img";
          }
          if (in_array(list[key]["file_ext"], ["mp4"])) {
            type = "video";
          }
          if (in_array(list[key]["file_ext"], ["zip", "rar"])) {
            type = "zip";
          }
          if (in_array(list[key]["file_ext"], ["mp3"])) {
            type = "audio";
          }
          state.dataList.push({
            storage_id: list[key]["storage_id"],
            name: list[key]["old_file_name"],
            src: list[key]["domain"] + list[key]["file_path"],
            type: type, //文件类型
          });
        }
        state.total = res.data.total;
      });
    };
    // 获取指定ID集文件列表
    const geIdsListfun = () => {
      if (state.activeList.length < 1) {
        state.filesList.length = 0;
        return false;
      }
      geIdsList({ ids: state.activeList }).then((res) => {
        state.filesList = res.data.list ? res.data.list : [];
      });
    };
    // 显示对话框
    const show = () => {
      getListfun();
      state.activeList.length = 0;
      state.activeList = deepCopy(props.active?props.active:[]);
      state.visible = state.visible ? false : true;
    };
    const activeChange = (storage_id) => {
      // 限制数量
      if (props.limit && state.activeList.length >= props.limit) {
        state.activeList.some((item, i) => {
          if (item == storage_id) {
            state.activeList.splice(i, 1);
            //在数组的some方法中，如果return true，就会立即终止这个数组的后续循环
            return true;
          }
        });
        return false;
      }
      // 追加减少数组
      if (in_array(storage_id, state.activeList)) {
        state.activeList.some((item, i) => {
          if (item == storage_id) {
            state.activeList.splice(i, 1);
            //在数组的some方法中，如果return true，就会立即终止这个数组的后续循环
            return true;
          }
        });
      } else {
        state.activeList.push(storage_id);
      }
      geIdsListfun();
      emit("changeActive", state.activeList);
    };
    // 搜索
    const onSearch = (searchValue) => {
      state.form.search = searchValue;
      getListfun();
    };

    // 页码变化
    const changePage = () => {
      getListfun();
    };
    // 删除图片
    const handleRemove = () => {};
    /* 限制文件大小，返回 boolean
     * file:文件对象
     * limiteSize:限制大小---例如："50MB"
     * */
    const limitFileSize = (file, limitSize) => {
      const arr = ["KB", "MB", "GB"];
      var limit = limitSize.toUpperCase();
      var limitNum = 0;
      for (var i = 0; i < arr.length; i++) {
        var leval = limit.indexOf(arr[i]);
        if (leval > -1) {
          limitNum = parseInt(limit.substr(0, leval)) * Math.pow(1024, i + 1);
          break;
        }
      }
      if (file.size > limitNum) {
        return false;
      }
      return true;
    };
    // 上传前
    const beforeUpload = (file, fileList) => {
      state.uploadList = fileList;
      // 如果是最后一次就触发上传，就上传，解决antd多文件上传多次触发bug
      if (json(fileList[fileList.length - 1]) === json(file)) {
        // 实例化一个对象
        var formData = new FormData();
        var retStatus = {
          status: false,
          msg: "",
        };
        for (var i = 0; i < fileList.length; i++) {
          // 限制文件大小
          if (!limitFileSize(fileList[i], "1MB")) {
            retStatus.status = true;
            retStatus.msg = "文件大小超出1M";
            break;
          }
          formData.append("files[]", fileList[i]);
        }
        if (retStatus.status) {
          notice("error", retStatus.msg, 2);
          return false;
        }
        batchUpload(formData).then((res) => {
          getListfun();
          if (res.status != "200") {
            notice("error", res.message, 2);
            return false;
          }
          notice("success", res.message);
        });
      }
      return false;
    };
    // 删除图片
    const deletes = () => {
      if (isEmptyObject(state.activeList)) {
        notice("error", "请至少选中一个文件", 2);
        return;
      }
      fileIdDelete({ ids: state.activeList }).then((res) => {
        if (res.status != "200") {
          notice("error", res.message, 2);
          return false;
        } else {
          getListfun();
          notice("success", res.message);
          return false;
        }
      });
    };

    const handleOk = () => {
      var filesList = [];
      if (state.activeList.length > 0) {
        filesList =
          state.filesList.length == 1 ? state.filesList[0] : state.filesList;
      } else {
        state.filesList.length = 0;
        filesList = [];
      }
      emit(
        "ok",
        state.activeList.length == 1 ? state.activeList[0] : state.activeList,
        filesList
      );
      state.visible = state.visible ? false : true;
    };
    return {
      show,
      in_array,
      onSearch,
      changePage,
      deletes,
      handleRemove,
      beforeUpload,
      activeChange,
      handleOk,
      ...toRefs(state),
    };
  },
});
</script>
<style lang="less" scoped>
:deep(.ant-modal) {
  .ant-modal-header {
    border: 0;
    padding: 16px 16px 10px 16px;
  }
  .ant-modal-body {
    padding: 0 6px;
  }
  .ant-modal-footer {
    border: 0;
    padding: 16px;
  }
}
.img-list {
  height: 490px;
  position: relative;
}
.img-footer {
  display: flex;
  justify-content: space-between;
  .img-footer-info {
    margin-right: 10px;
  }
  .img-footer-group {
    margin-right: 10px;
  }
  .img-footer-right {
    margin-right: 10px;
  }
}
.img-item {
  background: #fff;
  padding: 5px;
  cursor: pointer;
  margin-bottom: 10px;
  border-radius: 2px;
  height: 145px;
  transition: All 0.2s ease-in-out;
  position: relative;
  border: 1px #f2f2f2 solid;
}
.img-operation {
  padding-bottom: 10px;
}
.img-header-right {
  margin-left: 192px;
  .info {
    color: #c5bfbf;
    margin-right: 8px;
  }
}

.img-select-mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.41);
  text-align: center;
  border-radius: 2px;
  display: flex;
  justify-content: center;
  flex-direction: column;
}
.img-select-mask-check {
  color: #f5f5f5;
  font-size: 2rem;
  display: flex;
  justify-content: center;
}
.img-content {
  width: 100%;
  height: 110px;
  overflow: hidden;
  background-color: #f5f5f5;
}
.img-title {
  font-size: 12px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-top: 5px;
}
</style>